package edu.isistan.microops;

import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import edu.isistan.microops.rules.RulesEngine;


public class Main {

	private MicroopsCalculator microopsCalculator;

	
	public Main() {
		
	}
	
	/**
	 * Se encarga de establecer el orden de prioridades en el cual las reglas
	 * deben ser detectadas
	 */
	private void createMicroopsCalculator() {
		// Se crea el motor de Reglas y se lo assigna a microopsCalculator
		RulesEngine ruleEngine = new RulesEngine();
		// Aqui se concatenan los receptores
//		microopsCalculator = new ObjectMicroops(ruleEngine);
//		ArrayMicroops arrayMicroops = new ArrayMicroops(ruleEngine);
//		arrayMicroops.setNext(new AssignMicroops(ruleEngine));
//		microopsCalculator.setNext(arrayMicroops);
		
		microopsCalculator = new MicroopsCalculator(ruleEngine);

	}

	/**
     * Calcula las microoperaciones requeridas para adaptar dos
	 * interfaces dado el archivo de correspondencias. Se parsea el 
	 * xml y por cada entrada de mapping invoca el algoritmo.
	 * 
	 * @param fileName
	 *            : ruta del xml que contiene los mapeos de las interfaces a adaptar
	 * 
	 */
	public Vector<String> parse(String fileName) {
		//crea de nuevo el motor, borrando el listado de objetos creados en ejecuciones pasadas, etc.
		createMicroopsCalculator();
		
		Vector<String> microops = new Vector<String>();
		SAXBuilder builder = new SAXBuilder();		
		try {
			Document doc = builder.build(fileName);
			Element root = doc.getRootElement();
			Element mapping = root.getChild("mapping");
			@SuppressWarnings("unchecked")			
			List<Element> operations = mapping.getChildren();
			for (Element op : operations) {
				@SuppressWarnings("unchecked")
				List<Element> inMappings = op.getChild("inMessageMapping").getChildren();
				for (Element typeMapping : inMappings) {
					String sourceType = typeMapping.getAttribute("sourceType").getValue();
					String targetType = typeMapping.getAttribute("targetType").getValue();
					String sourceName = typeMapping.getAttribute("sourceName").getValue();
					String targetName = typeMapping.getAttribute("targetName").getValue();	
					microops.addAll(microopsCalculator.calculateMicroops(sourceName, sourceType, targetName, targetType));
				}
//				microops.add("---");
				@SuppressWarnings("unchecked")
				List<Element> outMappings = op.getChild("outMessageMapping").getChildren();
				for (Element typeMapping : outMappings) {
					String sourceType = typeMapping.getAttribute("sourceType").getValue();
					String targetType = typeMapping.getAttribute("targetType").getValue();	
					String sourceName = typeMapping.getAttribute("sourceName").getValue();
					String targetName = typeMapping.getAttribute("targetName").getValue();	
					microops.addAll(microopsCalculator.calculateMicroops(targetName, targetType, sourceName, sourceType));
				}
			}			
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return microops;
	}

	public static void main(String[] args) {
		Hashtable<String, Integer> resume = new Hashtable<String, Integer>();
		Main p = new Main();		
		File aux = null;
		for (int i=0; i<args.length; i++) {
			aux = new File(args[i]);
			if (aux.exists()) {				
				Vector<String> microops = p.parse(aux.getAbsolutePath());
				for (String mo : microops) {
					System.out.println(mo);
					String k = mo.split(",")[2];
					int q = 0;
					if (resume.containsKey(k))
						q = resume.get(k);
					q++;
					resume.put(k, q);
				}
			}			
		}
		for (String mo : resume.keySet()) {
			int q = resume.get(mo);
			System.out.println(mo + "," + q);
		}
	}
}
